package advertising

import (
	"advertising/config/mysql"
	"advertising/internal/app/grpc/client"
	"advertising/internal/app/grpc/protoc/advertisingc"
	"advertising/internal/app/grpc/protoc/system_admin"
	"advertising/internal/dao"
	"context"
	"strings"

	"github.com/samber/lo"
)

// 投放设备组列表
func (Server) PublishDeviceGroupList(ctx context.Context, req *advertisingc.PublishDeviceGroupListReq) (*advertisingc.PublishDeviceGroupListRsp, error) {
	res := &advertisingc.PublishDeviceGroupListRsp{}
	db := mysql.NewDB()
	DeviceGroupList, count, _ := dao.PublishDeviceGroup{}.PublishDeviceGroupList(ctx, db, req.Name, int(req.Page), int(req.Limit))
	res.Data = &advertisingc.PublishDeviceGroupListRsp_Data{}
	res.Data.Count = count
	for _, v := range DeviceGroupList {
		var item = &advertisingc.PublishDeviceGroupListRsp_Data_DeviceGroupList{}
		item.Id = v.ID
		item.Name = v.Name
		item.CreatedAt = int32(v.CreatedAt)
		item.UpdatedAt = int32(v.UpdatedAt)
		res.Data.List = append(res.Data.List, item)
	}
	return res, nil
}

// 投放设备组新增编辑
func (Server) PublishDeviceGroupSave(ctx context.Context, req *advertisingc.PublishDeviceGroupSaveReq) (*advertisingc.PublishDeviceGroupSaveRsp, error) {
	res := &advertisingc.PublishDeviceGroupSaveRsp{}
	res.Code = -1
	if strings.TrimSpace(req.Name) == "" {
		res.Msg = "设备分组名称不能为空"
		return res, nil
	}
	db := mysql.NewDB()
	if req.Id == "" { // 新增
		nameExist := dao.PublishDeviceGroup{}.SameNameExist(ctx, db, req.Name, "")
		if nameExist != 0 {
			res.Msg = "设备分组名称已经存在"
			return res, nil
		}
		dao.PublishDeviceGroup{}.Create(ctx, db, req.Name, int(req.Type))
	} else { // 编辑
		count := dao.PublishDeviceGroup{}.DeviceGroupExist(ctx, db, req.Id)
		if count == 0 {
			res.Msg = "设备分组不存在"
			return res, nil
		}

		nameExist := dao.PublishDeviceGroup{}.SameNameExist(ctx, db, req.Name, req.Id)
		if nameExist != 0 {
			res.Msg = "设备分组名称已经存在"
			return res, nil
		}
		dao.PublishDeviceGroup{}.Update(ctx, db, req.Id, strings.TrimSpace(req.Name))
	}
	res.Code = 0
	return res, nil
}

// 投放设备组删除
func (Server) PublishDeviceGroupDelete(ctx context.Context, req *advertisingc.PublishDeviceGroupDeleteReq) (*advertisingc.PublishDeviceGroupDeleteRsp, error) {
	res := &advertisingc.PublishDeviceGroupDeleteRsp{}
	if strings.TrimSpace(req.Id) == "" {
		res.Code, res.Msg = -1, "设备分组必须"
		return res, nil
	}
	db := mysql.NewDB()
	count := dao.PublishDeviceGroup{}.DeviceGroupExist(ctx, db, req.Id)
	if count == 0 {
		res.Code = -1
		res.Msg = "设备分组不存在"
		return res, nil
	}

	//判断设备分组是否在使用中
	_, GroupInUseCount := dao.MerchantPublishDeviceGroup{}.Detail(ctx, db, "", req.Id)
	if GroupInUseCount > 0 {
		res.Code = -1
		res.Msg = "设备分组正在使用中,无法删除"
		return res, nil
	}
	dao.PublishDeviceGroup{}.Delete(ctx, db, req.Id)
	return res, nil
}

// 投放设备组配置设备
func (Server) PublishDeviceGroupManage(ctx context.Context, req *advertisingc.PublishDeviceGroupManageReq) (*advertisingc.PublishDeviceGroupManageRsp, error) {
	res := &advertisingc.PublishDeviceGroupManageRsp{}
	if strings.TrimSpace(req.Id) == "" {
		res.Code = -1
		res.Msg = "设备分组必须"
		return res, nil
	}

	db := mysql.NewDB()
	count := dao.PublishDeviceGroup{}.DeviceGroupExist(ctx, db, req.Id)
	if count == 0 {
		res.Code = -1
		res.Msg = "设备分组不存在"
		return res, nil
	}
	OldDeviceList := dao.PublishDevice{}.GetRobotNameList(ctx, db, req.Id)
	// 新增 删除
	//deleteDevice  是 DeviceList没有的 即 需删除
	//addDevice  是 OldDeviceList没有的 即 新增的
	DeviceList := strings.Split(req.Devices, ",")
	deleteDevice, addDevice := lo.Difference(OldDeviceList, DeviceList)

	// 投放设备组关联的商户列表
	var MerchantList = []string{}
	merchantGroupList, _, _ := dao.MerchantPublishDeviceGroup{}.List(ctx, db, "", req.Id, 0, 0)
	for _, v := range merchantGroupList {
		MerchantList = append(MerchantList, v.MerchantID)
	}
	// 判断设备是否被计划使用，如被使用不允许删除
	if len(MerchantList) > 0 {
		// 查找所有计划
		scheduleList, _, _ := dao.PublishSchedule{}.List(ctx, db, strings.Join(MerchantList, ","), "", "", "", 0, 0, 0, 0, 0, 0, 0, 0, "", "", "", "", 0, 0)
		var scheduleIDList []string
		for _, v := range scheduleList {
			if v.Status != 5 && v.Status != 6 {
				scheduleIDList = append(scheduleIDList, v.ID)
			}
		}
		if len(deleteDevice) > 0 {
			// 查找计划中包含删除设备的计划 [true 不包含待删除的]
			_, UsingDeviceCount, _ := dao.PublishScheduleDevice{}.List(ctx, db, strings.Join(MerchantList, ","), strings.Join(scheduleIDList, ","), strings.Join(deleteDevice, ","), 0, 0, 0, true, 0, 0)
			if UsingDeviceCount > 0 {
				res.Code = -1
				res.Msg = "设备正在使用中，无法删除"
				return res, nil
			}
		}
	}
	if len(deleteDevice) > 0 {
		delErr := dao.PublishDevice{}.DeleteGroupDevice(ctx, db, req.Id, strings.Join(deleteDevice, ","))
		if delErr != nil {
			res.Code = -1
			res.Msg = delErr.Error()
			return res, nil
		}
	}
	// 新增设备
	for _, v := range addDevice {
		dao.PublishDevice{}.Create(ctx, db, v, req.Id)
	}
	return res, nil
}

// 投放设备组设备列表
func (Server) PublishDeviceList(ctx context.Context, req *advertisingc.PublishDeviceListReq) (*advertisingc.PublishDeviceListRsp, error) {
	res := &advertisingc.PublishDeviceListRsp{}
	if strings.TrimSpace(req.Id) == "" {
		res.Code = -1
		res.Msg = "设备分组必须"
		return res, nil
	}
	db := mysql.NewDB()
	count := dao.PublishDeviceGroup{}.DeviceGroupExist(ctx, db, req.Id)
	if count == 0 {
		res.Code = -1
		res.Msg = "设备分组不存在"
		return res, nil
	}
	res.Data = &advertisingc.PublishDeviceListRsp_Data{}
	DeviceList, count := dao.PublishDevice{}.GetDeviceListByGroupID(ctx, db, req.Id)
	res.Data.Count = count
	for _, v := range DeviceList {
		var item = &advertisingc.PublishDeviceListRsp_Data_PublishDeviceList{}
		item.Id = v.ID
		item.Name = v.RobotName
		item.CreatedAt = int32(v.CreatedAt)
		res.Data.List = append(res.Data.List, item)
	}
	return res, nil
}

// 商户列表
func (Server) PublishMerchantList(ctx context.Context, req *advertisingc.PublishMerchantListReq) (*advertisingc.PublishMerchantListRsp, error) {
	res := &advertisingc.PublishMerchantListRsp{}
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		res.Code = -1
		res.Msg = "获取商户列表失败"
		return res, nil
	}

	var merchantReq system_admin.MerchantListWithAdminUserReq
	merchantReq.Name = req.Name
	merchantReq.Page = req.Page
	merchantReq.Limit = req.Limit
	merchantRes, _ := SystemAdminClient.MerchantListWithAdminUser(ctx, &merchantReq)
	if merchantRes.Code != 0 {
		res.Code = -1
		res.Msg = "获取商户列表失败"
		return res, nil
	}
	res.Total = merchantRes.Total

	var MerchantIDList = []string{}
	for _, v := range merchantRes.List {
		if !lo.Contains(MerchantIDList, v.MerchantId) {
			MerchantIDList = append(MerchantIDList, v.MerchantId)
		}
	}
	//获取商户投放分组对应关系
	var MerchantPublishDeviceGroupList = []struct {
		MerchantID string
		GroupID    string
	}{}
	db := mysql.NewDB()
	MerchantGroupList, _, _ := dao.MerchantPublishDeviceGroup{}.List(ctx, db, strings.Join(MerchantIDList, ","), "", 0, 0)
	var GroupIDList = []string{}
	for _, v := range MerchantGroupList {
		MerchantPublishDeviceGroupList = append(MerchantPublishDeviceGroupList, struct {
			MerchantID string
			GroupID    string
		}{
			MerchantID: v.MerchantID,
			GroupID:    v.GroupID,
		})
		if !lo.Contains[string](GroupIDList, v.GroupID) {
			GroupIDList = append(GroupIDList, v.GroupID)
		}
	}
	// 查分组名称
	groupList, _ := dao.PublishDeviceGroup{}.List(ctx, db, strings.Join(GroupIDList, ","), 0)
	var groupIDNameMap = make(map[string]string)
	for _, v := range groupList {
		groupIDNameMap[v.ID] = v.Name
	}
	var MerchantGroupMap = make(map[string]struct {
		GroupID   string
		GroupName string
	})
	for _, v := range MerchantPublishDeviceGroupList {
		var groupName string
		if _, ok := groupIDNameMap[v.GroupID]; ok {
			groupName = groupIDNameMap[v.GroupID]
		}
		MerchantGroupMap[v.MerchantID] = struct {
			GroupID   string
			GroupName string
		}{
			GroupID:   v.GroupID,
			GroupName: groupName,
		}
	}
	//获取设备分组的设备数量
	GroupDeviceList := dao.PublishDevice{}.GroupRobotCount(ctx, db, strings.Join(GroupIDList, ","))
	var GroupDeviceCountMap = make(map[string]int64)
	for _, v := range GroupDeviceList {
		GroupDeviceCountMap[v.GroupID] = v.DeviceCount
	}
	for _, v := range merchantRes.List {
		var item = &advertisingc.PublishMerchantListRsp_MerchantList{}
		item.MerchantId = v.MerchantId
		item.MerchantName = v.MerchantName
		item.AdminUserId = v.AdminUserId
		item.AdminUserName = v.AdminUserName
		if _, ok := MerchantGroupMap[v.MerchantId]; ok {
			item.PublishDeviceGroupId = MerchantGroupMap[v.MerchantId].GroupID
			item.PublishDeviceGroupName = MerchantGroupMap[v.MerchantId].GroupName
		}
		if _, ok := GroupDeviceCountMap[item.PublishDeviceGroupId]; ok {
			item.DeviceCount = GroupDeviceCountMap[item.PublishDeviceGroupId]
		}
		res.List = append(res.List, item)
	}
	return res, nil
}

// 商户配置投放设备组
func (Server) PublishMerchantManage(ctx context.Context, req *advertisingc.PublishMerchantManageReq) (*advertisingc.PublishMerchantManageRsp, error) {
	res := &advertisingc.PublishMerchantManageRsp{}
	if req.MerchantId == "" {
		res.Code = -1
		res.Msg = "商户信息必须"
		return res, nil
	}
	if req.DeviceGroup == "" { // 设备组允许为空
		req.DeviceGroup = "0"
	}
	db := mysql.NewDB()
	_, count := dao.MerchantPublishDeviceGroup{}.Detail(ctx, db, req.MerchantId, "")
	if count == 0 {
		dao.MerchantPublishDeviceGroup{}.Create(ctx, db, req.MerchantId, req.DeviceGroup)
	} else {
		dao.MerchantPublishDeviceGroup{}.UpdateGoupID(ctx, db, req.MerchantId, req.DeviceGroup)
	}
	return res, nil
}
